---
title: Getting Started
---

import { Step, Steps } from "fumadocs-ui/components/steps";
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
import { Callout } from "fumadocs-ui/components/callout";
import { Card, Cards } from "fumadocs-ui/components/card";
import { InstallCommand } from "@/components/docs/install-command";

## Start with a new project

![animated gif showing the steps to create a new project](../../../../.github/assets/assistant-ui-starter.gif)

<Steps>
  <Step>

### Initialize assistant-ui

**Create a new project:**

```sh
# Create a new project with the default template
npx assistant-ui@latest create

# Or choose one of the following templates:
# Assistant Cloud for baked in persistence and thread management
npx assistant-ui@latest create -t cloud

# LangGraph
npx assistant-ui@latest create -t langgraph

# MCP support
npx assistant-ui@latest create -t mcp
```

**Add assistant-ui to an existing React project:**

```sh
# Add assistant-ui to an existing React project
npx assistant-ui@latest init
```

  </Step>
  <Step>

### Add API key

Add a new `.env` file to your project with your OpenAI API key:

```
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# chat history -- sign up for free on https://cloud.assistant-ui.com
# NEXT_PUBLIC_ASSISTANT_BASE_URL="https://..."
```

  </Step>
  <Step>

### Start the app

```sh
npm run dev
```

  </Step>
</Steps>

## Manual installation

<Callout>
  We recommend `npx assistant-ui init` to setup existing projects.
</Callout>

<Steps>
  <Step>

### Add assistant-ui

<InstallCommand shadcn={["thread", "thread-list"]} manualSetupInstructions />

  </Step>
  <Step>

### Setup Backend Endpoint

Install provider SDK:

<Tabs groupId="provider" items={["OpenAI", "Anthropic", "Azure", "AWS", "Gemini", "GCP", "Groq", "Fireworks", "Cohere", "Ollama", "Chrome AI"]}>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/openai"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/anthropic"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/azure"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/amazon-bedrock"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/google"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/google-vertex"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/openai"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/openai"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "@ai-sdk/cohere"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "ollama-ai-provider-v2"]} />
  </Tab>
  <Tab>
    <InstallCommand npm={["ai", "@assistant-ui/react-ai-sdk", "chrome-ai"]} />
  </Tab>
</Tabs>

Add an API endpoint:

<Tabs groupId="provider" items={["OpenAI", "Anthropic", "Azure", "AWS", "Gemini", "GCP", "Groq", "Fireworks", "Cohere", "Ollama", "Chrome AI"]}>
```ts title="/app/api/chat/route.ts" tab="OpenAI"
import { openai } from "@ai-sdk/openai";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: openai("gpt-4o-mini"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Anthropic"
import { anthropic } from "@ai-sdk/anthropic";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: anthropic("claude-3-5-sonnet-20240620"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Azure"
import { azure } from "@ai-sdk/azure";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: azure("your-deployment-name"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="AWS"
import { bedrock } from "@ai-sdk/amazon-bedrock";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: bedrock("anthropic.claude-3-5-sonnet-20240620-v1:0"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Gemini"
import { google } from "@ai-sdk/google";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: google("gemini-2.0-flash"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="GCP"
import { vertex } from "@ai-sdk/google-vertex";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: vertex("gemini-1.5-pro"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Groq"
import { createOpenAI } from "@ai-sdk/openai";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

const groq = createOpenAI({
  apiKey: process.env.GROQ_API_KEY ?? "",
  baseURL: "https://api.groq.com/openai/v1",
});

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: groq("llama3-70b-8192"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Fireworks"
import { createOpenAI } from "@ai-sdk/openai";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

const fireworks = createOpenAI({
  apiKey: process.env.FIREWORKS_API_KEY ?? "",
  baseURL: "https://api.fireworks.ai/inference/v1",
});

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: fireworks("accounts/fireworks/models/firefunction-v2"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Cohere"
import { cohere } from "@ai-sdk/cohere";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: cohere("command-r-plus"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Ollama"
import { ollama } from "ollama-ai-provider-v2";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: ollama("llama3"),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

```ts title="/app/api/chat/route.ts" tab="Chrome AI"
import { chromeai } from "chrome-ai";
import { convertToModelMessages, streamText } from "ai";

export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = streamText({
    model: chromeai(),
    messages: convertToModelMessages(messages),
  });
  return result.toUIMessageStreamResponse();
}
```

</Tabs>

Define environment variables:

<Tabs groupId="provider" items={["OpenAI", "Anthropic", "Azure", "AWS", "Gemini", "GCP", "Groq", "Fireworks", "Cohere", "Ollama", "Chrome AI"]}>

```sh title="/.env.local" tab="OpenAI"
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="Anthropic"
ANTHROPIC_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="Azure"
AZURE_RESOURCE_NAME="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AZURE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="AWS"
AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AWS_REGION="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="Gemini"
GOOGLE_GENERATIVE_AI_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="GCP"
GOOGLE_VERTEX_PROJECT="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
GOOGLE_VERTEX_LOCATION="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
GOOGLE_APPLICATION_CREDENTIALS="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="Groq"
GROQ_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="Fireworks"
FIREWORKS_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh title="/.env.local" tab="Cohere"
COHERE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```sh tab="Ollama"
<none>
```

```sh tab="Chrome AI"
<none>
```

</Tabs>

If you aren't using Next.js, you can also deploy this endpoint to Cloudflare Workers, or any other serverless platform.

  </Step>

  <Step>

### Use it in your app

<Tabs items={["Thread", "AssistantModal"]}>

```tsx title="/app/page.tsx" tab="Thread"
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/react-ai-sdk";
import { ThreadList } from "@/components/assistant-ui/thread-list";
import { Thread } from "@/components/assistant-ui/thread";

const MyApp = () => {
  const runtime = useChatRuntime({
    transport: new AssistantChatTransport({
      api: "/api/chat",
    }),
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <div>
        <ThreadList />
        <Thread />
      </div>
    </AssistantRuntimeProvider>
  );
};
```

```tsx title="/app/page.tsx" tab="AssistantModal"
// run `npx shadcn@latest add @assistant-ui/assistant-modal`

import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/react-ai-sdk";
import { AssistantModal } from "@/components/assistant-ui/assistant-modal";

const MyApp = () => {
  const runtime = useChatRuntime({
    transport: new AssistantChatTransport({
      api: "/api/chat",
    }),
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <AssistantModal />
    </AssistantRuntimeProvider>
  );
};
```

</Tabs>

</Step>
</Steps>

## What's Next?

<Cards>
  <Card
    title="Pick a Runtime"
    description="Choose the right runtime for your needs"
    href="/docs/runtimes/pick-a-runtime"
  />
  <Card
    title="Generative UI"
    description="Create rich UI components for tool executions"
    href="/docs/guides/ToolUI"
  />
  <Card
    title="Add Persistence"
    description="Save and restore chat conversations"
    href="/docs/cloud/overview"
  />
  <Card
    title="Examples"
    description="Explore full implementations and demos"
    href="https://github.com/assistant-ui/assistant-ui/tree/main/examples"
  />
</Cards>
